﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;

namespace Utils.JobTask
{

    class JobService<E> : IJobService<E>
    {
        private readonly JobProvider jobService;


        private readonly int retryCount = 3;
        public JobService(IJobProvider jobService)
        {
            this.jobService = jobService as JobProvider;
        }
        public void Execute(int countdown, Expression<Func<E, Action>> expression)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method);
        }

        public void Execute<T>(int countdown, Expression<Func<E, Action<T>>> expression, T arg)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg);
        }
        public void Execute<T, T2>(int countdown, Expression<Func<E, Action<T, T2>>> expression, T arg, T2 arg2)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2);
        }
        public void Execute<T, T2, T3>(int countdown, Expression<Func<E, Action<T, T2, T3>>> expression, T arg, T2 arg2, T3 arg3)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2, arg3);
        }
        public void Execute<T, T2, T3, T4>(int countdown, Expression<Func<E, Action<T, T2, T3, T4>>> expression, T arg, T2 arg2, T3 arg3, T4 arg4)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2, arg3, arg4);
        }
        public void Execute(int countdown, Expression<Func<E, Func<Task>>> expression)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method);
        }

        public void Execute<T>(int countdown, Expression<Func<E, Func<T, Task>>> expression, T arg)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg);
        }

        public void Execute<T, T2>(int countdown, Expression<Func<E, Func<T, T2, Task>>> expression, T arg, T2 arg2)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2);
        }

        public void Execute<T, T2, T3>(int countdown, Expression<Func<E, Func<T, T2, T3, Task>>> expression, T arg, T2 arg2, T3 arg3)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2, arg3);
        }



        public void Execute<T, T2, T3, T4>(int countdown, Expression<Func<E, Func<T, T2, T3, T4, Task>>> expression, T arg, T2 arg2, T3 arg3, T4 arg4)
        {
            jobService.Add(countdown, retryCount, expression.Compile().Invoke(default).Method, arg, arg2, arg3, arg4);
        }
    }

}
